<?php

class Controller
{

    /**
     * @var Request
     */
    protected $_request = null;

    /**
     * action name
     * @var string
     */
    protected $_actionName = 'index';

    /**
     * scripts file.
     * @var string
     */
    protected $_script = null;

    /**
     * no render
     * @var bool
     */
    protected $_noRender = 0;

    /**
     * @var string
     */
    protected $_required = null;

    /**
     * data collect
     * @var array
     */
    public $data = array();

    /**
     * enalbe/disable render
     * @param bool $flag
     * @return Controller
     */
    public function setNoRender($flag)
    {
        $this -> _noRender = (bool)$flag;
    }

    /**
     * check is no render?
     * @return bool
     */
    public function isNoRender()
    {
        return $this -> _noRender;
    }

    /**
     * constructor
     * @return void
     */
    public function __construct($request)
    {
        $this -> _request = $request;
        $this -> init();
    }

    /**
     * require init action
     */
    public function init()
    {

    }

    /**
     * @param string $action
     * @return void
     */
    public function dispatch($actionName = 'index')
    {
        // allow admin access only
        $method = $this -> getMethodName($actionName);

        $this -> _actionName = $actionName;

        if (!method_exists($this, $method))
        {
            throw new Exception(get_class($this) . "::$method not found.");
        }

        $this -> _request -> setDispatched(1);

        $this -> {$method}();
    }

    /**
     * get method name from action name
     * @param string $string
     * @return string
     */
    static public function getMethodName($string)
    {
        $string = inflect_string($string);
        return strtolower(substr($string, 0, 1)) . substr($string, 1) . 'Action';
    }

    /**
     * set action name
     * @param string $actionName
     * @return Controller
     */
    public function setActionName($actionName)
    {
        $this -> _actionName = $actionName;
        return $this;
    }

    /**
     * get action name
     * @return string
     */
    public function getActionName()
    {
        return $this -> _actionName;
    }

    /**
     * set script
     * @param string $script
     * @return Controller
     */
    public function setScript($script)
    {
        $this -> _script = $script;
        return $this;
    }

    /**
     * get script
     * @return string
     */
    public function getScript()
    {
        if (null == $this -> _script)
        {
            $this -> _script = 'module/' . str_replace('_', '/', str_replace('_controller_', '_views_', strtolower(get_class($this)))) . '/' . $this -> _actionName . '.tpl';
        }
        return $this -> _script;
    }

    /**
     * render script and data
     */
    public function render()
    {
        if ($this -> _noRender)
        {
            return '';
        }
        return View::render($this -> data, $this -> getScript(), 1, null);
    }

    /**
     * @return Request
     */
    public function getRequest()
    {
        return $this -> _request;
    }

    /**
     * @param Request $request
     * @return Controller
     */
    public function setRequest($request)
    {
        $this -> _request = $request;
        return $this;
    }

    /**
     * @param string $key
     * @param any $value
     * @return Controller
     */
    public function __set($key, $value)
    {
        $this -> data[$key] = $value;
        return $this;
    }

    public function redirect($url ='', $params = null)
    {
        Nuo::getResponse()->redirect($url, $params);
    }

}
